const HeaderCore = (function () {
  const DATA_INDEX_CONCAT_CHAR = "<>";
  const H = {
    // key拼接
    keyJoin: function (...args) {
      return args.filter((i) => typeof i !== "undefined").join(DATA_INDEX_CONCAT_CHAR);
    },

    /**
     * 创建新的字段
     * @param {string} title 字段名称
     * @param {string|number} id ID
     * @param {string|number} pid 上级ID
     * @param {number} sort 排序值
     * @returns {IColumn} 新字段
     */
    createNewColumn: function(name, id, pid, sort) {
      return {
        title: name,
        key: id,
        parentKey: pid,
        dataIndex: id,
        sort: sort,
      };
    },

    // 格式化维度字段
    formatMetricColumn: function (metricGroupConfigs) {
      const metricColumn = [];
      metricGroupConfigs.forEach((item, idx) => {
        let row = [];
        row.push(item.metricConfig);
        if (item.compareDimensionConfigs && item.compareDimensionConfigs.length > 0) {
          row = row.concat(item.compareDimensionConfigs);
        }
        metricColumn.push(row);
      });
      return metricColumn;
    },

    // 创建基础字段列表
    createBaseColumn: function (dimension, metric) {
      let columns = [];

      // 维度字段（也就是没有分组的字段）
      let dimensionColumns = dimension.map(({ tableColumn, ...rest }) => {
        return {
          ...rest,
          tableColumn,
          title: tableColumn.alias,
          key: tableColumn.name,
          dataIndex: tableColumn.name,
        };
      });
      columns = columns.concat(dimensionColumns);
      
      // 度量字段(分组字段)
      metric.forEach((item, index) => {
        if (item.length > 0) {
          const { tableColumn, ...rest } = item[0];
          let metricColumn = [
            {
              ...rest,
              tableColumn,
              title: tableColumn.alias,
              key: index + DATA_INDEX_CONCAT_CHAR + tableColumn.name,
              dataIndex: index + DATA_INDEX_CONCAT_CHAR + tableColumn.name,
            },
          ];
          columns = columns.concat(metricColumn);
        }
      });
      return columns;
    },

    // 生成子集表头
    generatorChildren: function (data, dataIndex, total, rootKey, __parentKey) {
      if (dataIndex >= total) return [];
      /**
       * TODO:
       * __parentKey 为递归执行条件参数，调用无需传递
       * 目前过滤数据逻辑是，上下级关系，是通过当前的父索引是否等于__parentKey
       * 上下级关系取决于下标的位置
       * String(rows[dataIndex - 1]) === parentKey;
       */
      const parentKey = __parentKey ? __parentKey.split(DATA_INDEX_CONCAT_CHAR).slice(-1)[0] : null;
      const sourceData = parentKey
        ? data.filter((rows) => {
            // TODO: 当前字段是否为parentKey的下级
            return String(rows[dataIndex - 1]) === parentKey;
          })
        : data;

      // 获取到统计的字段名，并做去重处理
      let _columns = [...new Set(sourceData.map((itm) => itm[dataIndex]))];

      // 遍历所有data字段，并组装格式
      return _columns.map((columnName) => {
        const key = __parentKey ? H.keyJoin(__parentKey, columnName) : H.keyJoin(rootKey, columnName);
        const col = H.createNewColumn(String(columnName), key, __parentKey || rootKey, 0);
        const children = H.generatorChildren(data, dataIndex + 1, total, rootKey, key);
        if (children && children.length) {
          col.children = children;
        }
        return col;
      });
    },
    
    // 设置字段排序
    setColumnsSort: function (columns) {
      let sortValue = 1;
      const _walk = function (data) {
        for (let i = 0; i < data.length; i++) {
          data[i].sort = sortValue++;
          if (data[i].children) {
            _walk(data[i].children);
          }
        }
      }
      _walk(columns)
    },

    // 创建字段列表
    createColumn: function (columns, metricColumn, data) {
      const dataGroup = {};
      const MIN_COLUMN_SIZE = 2; // 最小字段组长度
      // 通过字段分组
      columns.forEach((column, index) => {
        dataGroup[column.dataIndex] = data.map((row) => row[index]);
      });
      for (let i = 0, len = metricColumn.length; i < len; i++) {
        const item = metricColumn[i];
        // 分组字段里面的内容必须是多维数组
        if (!item || !Array.isArray(item) || item.length === 0) continue;
        const element = item[0];

        // TODO: 找到当前第一个分组字段在字段列表中的索引位置；
        const columnIndex = columns.findIndex((itm) => itm.dataIndex === H.keyJoin(i, element.tableColumn.name));

        // 如果没有找到直接结束本次循环
        if (columnIndex === -1) continue;

        // 接口返回的原始数组
        const colGroupData = dataGroup[columns[columnIndex].dataIndex];

        // 将数据扁平化，多层数组转为一层数组
        let arrayData = colGroupData.reduce((res, cur) => (res = res.concat(cur)), []);

        // 数组里面的内容必须为一个数组，也就是所谓的字段
        if (!Array.isArray(arrayData[0])) continue;

        // 当前字段的分组层级
        const columnDeepSize = arrayData[0].length;

        // 层级必须大于2层，否则不算多级表头
        if (columnDeepSize <= MIN_COLUMN_SIZE) {
          // 从头部（也就是下标1,下标0为值）开始分组
          const firstGroups = [...new Set(arrayData.map((itm) => itm[1]))];

          // 当前组装好的字段
          const newColumn = firstGroups.map((k) => {
            const dataIndex = H.keyJoin(i, k);
            return H.createNewColumn(String(k), dataIndex, columns[columnIndex].dataIndex, 0);
          });
          columns[columnIndex].children = newColumn;
          continue;
        }

        // 把当前处理好的数据赋值给第一层表头
        columns[columnIndex].children = H.generatorChildren(arrayData, 1, arrayData[0].length, columns[columnIndex].dataIndex);
      }
      H.setColumnsSort(columns); // 设置排序
      return columns;
    }
  };

  const P = {
    /**
     * 获取合并列的数量
     * @param {*} data 
     * @returns 
     */
    getColumnCount(data) {
      let count = 0;
      if (!data) return count;
      const { children } = data;
      if (!children) return count;
      for (let i = 0, len = children.length; i < len; i++) {
        count += children[i].children ? P.getColumnCount(children[i]) : 1;
      }
      return count;
    },

    /**
     * 检测列表是否存在下一级
     * @param {array} data 
     * @returns {boolean}
     */
    isHaveChildren(data) {
      if (!data) return false;
      for (let i = 0, len = data.length; i < len; i++) {
        let item = data[i];
        if (Array.isArray(item.children) && item.children.length > 0) {
          return true;
        }
      }
      return false;
    },

    /**
     * 序列化头
     * @param {*} dataTee 
     * @returns 
     */
    parseHeader(dataTee) {
      const _d = JSON.parse(JSON.stringify(dataTee));
      let resultGroup = {};
      const _walk = (data, __level = 1) => {
        const groupKey = `level_${__level}`;
        for (let i = 0, len = data.length; i < len; i++) {
          const column = data[i];
          // 是否存在子集
          if (column.children && column.children.length) {
            column.rowspan = 1;
            column.colspan = P.getColumnCount(column);
            _walk(column.children, __level + 1); // 继续往下走
          } else {
            column.rowspan = data.length || 1;
            column.colspan = 1;
          }
          if (!resultGroup[groupKey]) {
            resultGroup[groupKey] = []
          }
          resultGroup[groupKey].push(column)
        }
        return resultGroup;
      }
      return Object.keys(_walk(_d))
        .sort()
        .map(key => resultGroup[key]);
    }
  };

  /**
   * 创建表格
   * @param {*} headerConfig 
   * @param {*} data 
   * @returns 
   */
  function create(headerConfig, data) {
    const metricColumn = H.formatMetricColumn(headerConfig.metricGroupConfigs);
    const columns = H.createBaseColumn(headerConfig.dimensionConfigs, metricColumn);
    const tableColumnTree = H.createColumn(columns, metricColumn, data);
    console.log('tableColumnTree', tableColumnTree)
    const tableHeader = P.parseHeader(tableColumnTree);
    return { columns, tableColumnTree, metricColumn, tableHeader };
  }

  return {
    create
  }
})();
